use crate::base64ct::{Base64, Encoding};
use crate::field::{VddField, VddFieldType};
use crate::id_factory::SnowflakeIdGenerator;
use crate::model::DataStore;
use crate::query::VddValueEvaluation;
use crate::visit::{VisitGroupType, ShareRuleOfModel};
use crate::{i18n, to_sha256_hash, FieldId, EMPTY_FID};
use base64ct::LineEnding;
use chrono::{Local, TimeZone};
use rsa::pkcs1::EncodeRsaPrivateKey;
use rsa::pkcs8::EncodePublicKey;

use std::any::type_name_of_val;
use std::process::{Command, Stdio};
use std::sync::Arc;
use std::time::SystemTime;
use std::u16;

#[test]
fn test_type_name() {
    let fve = VddValueEvaluation::FveEqual(EMPTY_FID, "".into());
    println!("{:?}", type_name_of_val(&fve));
}

#[test]
fn test_format() {
    let s = format!("{{{}}}", 0);
    println!("{}", s);
    let i = 89;
    let s = format!("{{{i}}}");
    println!("{}", s);
}

#[test]
fn test_sudo() {
    let o = Command::new("echo")
        .arg("somepassword")
        .stdout(Stdio::piped())
        .spawn()
        .unwrap();
    let out = Command::new("sudo")
        .arg("-S")
        .stdin(o.stdout.unwrap())
        .arg("/usr/bin/id")
        .output();
    print!("{:?}", out);
}

#[test]
fn os_info() {
    println!("{:?}", std::env::temp_dir());
    println!("{:?}", std::env::current_dir().unwrap());
    // println!("{:?}",std::env::vars_os());
    println!("{:?}", std::env::args_os());
    println!("{:?}", std::env::args());
}

#[test]
fn decode() {
    let b64str = "vOTt9vLkQapImW12V3JvP+6R8ioQnlgImAAuHMlGw1bM+3lkUvBDWjbWWkUWTHG7wTSVU4+9Nvnp3DfTmHmfxWlgH3hO1z4lreEaoKNqOiZThwigCfp+uzO0k91YNvvZTDIif9phWvkze7Jr1niH9uq9MtucAISLRxawXtstc8v6yMwOyWYkRWPHKYPDrp27+N3nOQfkr80RQz0jQG07phiZCWZVB/GrSB0M8j9/qD3JY/d38jt4FInvLKJLh75c0ubE4mbnS8RNIKJulaYoyt5mmFwvMAacM5gB6jtWAC9fC9rkoL9jTlz+G9fwSAwP/eE8M1lEJ5pD0kksGneGJw==";
    let content = Base64::decode_vec(b64str).expect("base64编码字符串解析失败");
    println!("{:?}", content);
}

#[test]
fn test_vec() {
    let v = vec![
        1, 3, 5, 8, 5, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
        27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 3,
    ];
    print!("v[0]={}", v[0]);
    v[1..].iter().for_each(|x| println!("{}", x));
}

#[test]
fn test_sha256() {
    let result = to_sha256_hash("a man is your 爸爸");
    println!("{}", result);
    // hasher.
    // hasher.update("I am your 爷爷");
    // let result = hasher.finalize();
    // let result = hex::encode(result[..].to_vec());
    // println!("{}",result);
}

#[test]
fn test_split() {
    let s = "a/b/c".to_string();
    let splited: Vec<&str> = s.split("/").collect();
    println!("{:?}", splited);
    println!("{}", splited.last().unwrap());
}

#[test]
fn test_generate() {
    let mut id_generator = SnowflakeIdGenerator::new(1);
    let mut ids = Vec::with_capacity(10000);

    for _ in 0..99 {
        for _ in 0..10000 {
            ids.push(id_generator.lazy_generate());
        }

        ids.sort();
        ids.dedup();

        assert_eq!(10000, ids.len());
        println!("{}", ids[9999]);

        ids.clear();
    }
}

#[test]
fn test_real_time_generate() {
    let mut id_generator = SnowflakeIdGenerator::new(2);
    let mut ids = Vec::with_capacity(10000);

    for _ in 0..99 {
        for _ in 0..10000 {
            ids.push(id_generator.real_time_generate());
        }

        ids.sort();
        ids.dedup();

        assert_eq!(10000, ids.len());
        println!("{}", ids[9999]);

        ids.clear();
    }
}

#[test]
fn test_lazy_generate() {
    let mut id_generator = SnowflakeIdGenerator::new(3);
    let mut ids = Vec::with_capacity(10000);

    for _ in 0..100 {
        for _ in 0..10000 {
            let id = id_generator.lazy_generate();
            // println!("{}", id);
            ids.push(id);
        }

        ids.sort();
        ids.dedup();

        assert_eq!(10000, ids.len());
        println!("{}", ids[9999]);

        ids.clear();
    }
}

#[test]
fn test_simple() {
    let ts = Local.with_ymd_and_hms(2024, 1, 1, 0, 0, 0).unwrap();
    let mut id_generator = SnowflakeIdGenerator::with_epoch(0, SystemTime::from(ts));
    for _ in 0..99 {
        println!("{}", id_generator.generate());
    }
}

#[test]
fn test_any() {
    let v_range = ShareRuleOfModel::VrAuthor(true, true, true);
    print!("{:?}", std::any::type_name_of_val(&v_range));
    let v_t = VisitGroupType::VgtCode {
        k: "xxxeee".into(),
        c: 345678,
    };
    print!("{:?}", std::any::type_name_of_val(&v_t));
}

#[test]
fn test_rsa_key() {
    let pri_key = rsa::RsaPrivateKey::new(&mut rand::thread_rng(), 512).unwrap();
    let pub_key = pri_key.clone().to_public_key();
    // let s = pri_key.d().to_string();
    // println!("{}", s);
    println!(
        "{:?}",
        pri_key.to_pkcs1_pem(LineEnding::LF).unwrap().to_string()
    );
    // let s = pub_key.e().to_string();
    // println!("{}", s);
    // let s = pub_key.n().to_string();
    // println!("{}", s);
    println!("{:?}", pub_key.to_public_key_pem(LineEnding::LF).unwrap());
}

#[test]
fn test_format_f64() {
    let f = 3.221634;
    println!("{:.1$}", f, 3);
}

#[test]
fn test_i18n_format() {
    let i = "abcd";
    // let s = _i18n_format(&TemplateKey(1203), &vec![1234, 8900]);
    let s = i18n!(1203, "1234", i);
    println!("{}", s);
}

#[test]
fn rmp_case() {
    // success case
    // let obj = DataStore {
    //     store_engine: DataStoreEngine::Mysql,
    //     host: IpAddr::V4(Ipv4Addr::new(192, 168, 1, 3)),
    //     port: 3306,
    //     user: "visitdd".into(),
    //     password: "visitdd".into(),
    //     store_family_name: "visitdd".into(),
    //     remote_key: "visitdd".into(),
    //     remote_primary_key: "visitdd".into(),
    // };
    // failure case
    // let obj = VddValue::S401 {
    //     v: 233,
    //     d: "kkk.jpg".into(),
    // };
    // failure case
    let obj = VddField {
        id: FieldId(3534),
        model_id: 11,
        display_order: 1,
        label: "dsds".into(),
        field_type: Arc::new(VddFieldType::FtFile(u16::MAX)),
        required: true,
        multi: false,
        unique: true,
        update_ts: Local::now().naive_local(),
        input_hint: Some("中文版".into()),
    };
    let vu8 = rmp_serde::to_vec(&obj).unwrap();
    println!("{:?}", &vu8);
    let obj2 = rmp_serde::from_slice::<DataStore>(&vu8).unwrap();
    println!("{:?}", obj2);
}
